package com.xl;

import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

import static org.junit.jupiter.api.Assertions.*;

// 对 Calculator 类进行单元测试，测试每个运算方法的正确性
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class CalculatorTest {

    // 声明一个 Calculator 类的实例，供测试使用
    Calculator calculator;

    // 在每个测试方法执行前初始化一个新的 Calculator 实例
    @BeforeEach
    public void setUp() {
        calculator = new Calculator();  // 每个测试方法前都会执行
    }

    // 在每个测试方法执行后清理工作，确保每个测试方法都独立
    @AfterEach
    public void tearDown() {
        calculator = null;  // 每个测试方法后都会执行
    }

    // 测试加法功能，设置执行顺序为第1个
    @Test
    @Order(1)
    @DisplayName("测试加法功能")  // 添加了自定义名称，方便在控制台查看测试输出。
    public void testAdd() {
        // 使用断言方法（如 assertEquals）来验证结果的正确性
        // 断言：2 + 3 应该等于 5
        assertEquals(5, calculator.add(2, 3), "2 + 3 应该等于 5");
    }

    // 测试减法功能，设置执行顺序为第2个
    @Test
    @Order(2)
    @DisplayName("测试减法功能")
    public void testSubtract() {
        // 断言：3 - 2 应该等于 1
        assertEquals(1, calculator.subtract(3, 2), "3 - 2 应该等于 1");
    }

    // 测试乘法功能，设置执行顺序为第3个
    @Test
    @Order(3)
    @DisplayName("测试乘法功能")
    public void testMultiply() {
        // 断言：2 * 3 应该等于 6
        assertEquals(6, calculator.multiply(2, 3), "2 * 3 应该等于 6");
    }

    // 测试除法功能，设置执行顺序为第4个
    @Test
    @Order(4)
    @DisplayName("测试除法功能")
    public void testDivide() {
        // 断言：6 / 3 应该等于 2
        assertEquals(2, calculator.divide(6, 3), "6 / 3 应该等于 2");
    }

    // 重复执行3次的测试方法，确保加法功能的稳定性
    @RepeatedTest(3)
    @DisplayName("测试加法功能（重复测试）")
    public void testAddRepeatedly() {
        // 断言：2 + 3 应该等于 5
        assertEquals(5, calculator.add(2, 3), "2 + 3 应该等于 5");
    }

    // 参数化测试，使用不同的整数值进行加法测试
    @ParameterizedTest
    @ValueSource(ints = {1, 2, 3, 4, 5})
    @DisplayName("测试加法功能（参数化测试）")
    public void testAddWithDifferentValues(int value) {
        // 断言：value + 2 的结果应该等于 value + 2
        assertEquals(value + 2, calculator.add(value, 2), "加法计算失败");
    }

    // 嵌套测试：用于组织相关的测试，增加代码的可读性
    // 本例将加法和减法的测试分别放入 AdditionTests 和 SubtractionTests 嵌套类中
    @Nested
    class AdditionTests {
        @Test
        @DisplayName("测试加法")
        public void testAdd() {
            // 断言：2 + 3 应该等于 5
            assertEquals(5, calculator.add(2, 3));
        }
    }

    @Nested
    class SubtractionTests {
        @Test
        @DisplayName("测试减法")
        public void testSubtract() {
            // 演示如何使用 Calculator 类进行加法操作
            // 断言：3 - 2 应该等于 1
            assertEquals(1, calculator.subtract(3, 2));
        }
    }
}

class Calculator {
    // 加法方法
    public int add(int a, int b) {
        return a + b;
    }

    // 减法方法
    public int subtract(int a, int b) {
        return a - b;
    }

    // 乘法方法
    public int multiply(int a, int b) {
        return a * b;
    }

    // 除法方法
    public int divide(int a, int b) {
        if (b == 0) {
            throw new IllegalArgumentException("除数不能为零");
        }
        return a / b;
    }
}